package net.worldscale.xp.wslib.urm;

import net.worldscale.xp.wslib.urm.io.Connector;
import net.worldscale.xp.wspr.ModuleInfo;

final class ImplURM extends URM {

    private final AppManager mAppMan = new ImplAppManager();
    private final Connector mConnector = new ImplConnector();
    private final Connector mConnectorImpl = new ImplConnector();

    public ImplURM() {
    }

    @Override
    public Connector getConnectorImpl() {
        return this.mConnectorImpl;
    }

    @Override
    public ModuleInfo getInfo() {
        return (new UrmFactory()).getInfo();
    }

    @Override
    public AppManager getAppManager() {
        return mAppMan;
    }

    @Override
    public Connector getConnector() {
        return mConnector;
    }

    @Override
    public MimeType newMimeType(String mime) {
        return ImplMimeType.newInstance(mime);
    }

    @Override
    public URI newURI(String uri) throws BadUriException {
        return ImplURI.newInstance(uri);
    }

    @Override
    public URI newURI(String scheme, String host, String port,
            String path, String query, String frag) throws BadUriException {
        StringBuffer uri = new StringBuffer();
        if (scheme != null) {
            uri.append(scheme + ":");
        }
        if (host != null) {
            uri.append("//" + host);
        }
        if (port != null) {
            uri.append(":" + port);
        }
        if (path != null) {
            uri.append(path);
        }
        if (query != null) {
            uri.append("?" + query);
        }
        if (frag != null) {
            uri.append("#" + frag);
        }
        return newURI(uri.toString());
    }

    @Override
    public URI calcURI(String base, String offset) throws BadUriException {
        return calcURI(newURI(base), newURI(offset));
    }

    private static String calcPath(String base, String offset) {
        if (offset.startsWith("/")) {
            return offset;
        }
        final int i = base.lastIndexOf('/');
        if (i < 0) {
            return offset;
        }
        return base.substring(0, i + 1) + offset;
    }

    @Override
    public URI calcURI(URI base, URI offset) throws BadUriException {
        String scheme, host, port, path, query, frag;
        scheme = offset.getScheme();
        host = offset.getHost();
        port = offset.getPort();
        path = offset.getPath();
        query = offset.getQuery();
        frag = offset.getFragment();
        if (scheme == null) {
            scheme = base.getScheme();
            if (host == null) {
                host = base.getHost();
                port = base.getPort();
                if (path == null) {
                    path = base.getPath();
                    if (query == null) {
                        query = base.getQuery();
                    }
                }
            }
        }
        if (path != null) {
            if (!path.startsWith("/")) {
                path = calcPath(base.getPath(), path);
            }
        }
        return newURI(scheme, host, port, path, query, frag);
    }
}
